#ifndef STX_ALGORITHM_REVERSE_HPP_
#define STX_ALGORITHM_REVERSE_HPP_

#include <stx/algorithm/common.hpp>
#include <stx/algorithm/swap.hpp>

namespace stx {

template <class BidirectionalIterator>
inline void
reverse_impl(BidirectionalIterator first, BidirectionalIterator last, std::bidirectional_iterator_tag)
{
    while (first != last) {
        if (first == --last) {
            break;
        }
        stx::swap(*first, *last);
        ++first;
    }
}

template <class RandomAccessIterator>
inline void
reverse_impl(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag)
{
    if (first != last) {
        for (; first < --last; ++first) {
            stx::swap(*first, *last);
        }
    }
}

template <class BidirectionalIterator>
inline void
reverse(BidirectionalIterator first, BidirectionalIterator last)
{
    stx::reverse_impl(first, last, typename std::iterator_traits<BidirectionalIterator>::iterator_category());
}

} // namespace stx

#endif // STX_ALGORITHM_REVERSE_HPP_
